import {
  createRouter,
  createWebHashHistory,
  RouteRecordRaw,
  RouteLocationNormalized
} from 'vue-router'
import { useStorage, useStorageType } from '@/utils'
import { TOKEN, ROUTE_WHITE_LIST, LOGIN_PATH } from '@/constants'
// import { useUserStore } from '@/store/user'
import { useLayoutStore } from '@/store/layout'
import NProgress from '@/plugins/NProgress' // 引入顶部进度条插件

// 公开路由表
const routes: RouteRecordRaw[] = [
  {
    name: 'Login',
    path: LOGIN_PATH,
    component: () => import(/* webpackChunkName: "login" */ '@/views/login/index.vue')
  },
  {
    name: 'Layout',
    path: '/',
    redirect: '/main',
    component: () => import(/* webpackChunkName: "layout" */ '@/layout/index.vue'),
    children: [
      /* {
        name: 'Main',
        path: '/main',
        meta: {
          title: '首页',
          icon: 'location'
        },
        component: () => import('@/views/main/index.vue')
      } */
    ]
  }
  /*  {
      name: '404',
      path: '/404',
      meta: {
        title: '页面未找到'
      },
      component: () => import(/!* webpackChunkName: "404" *!/ '@/views/error/404.vue')
    },
    {
      path: '/:pathMatch(.*)*',
      redirect: '/404' // 路径不对跳转该页面
    } */
]

const router = createRouter({
  history: createWebHashHistory(),
  routes,
  /**
   * 滚动行为
   * @param to: 即将要进入的目标 用一种标准化的方式
   * @param from: 当前导航正要离开的路由 用一种标准化的方式
   * @param savedPosition: popstate 导航时才可用（由浏览器的后退/前进按钮触发）
   */
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      // 返回 savedPosition，在按下 后退/前进 按钮时，就会像浏览器的原生表现那样
      return savedPosition
    } else {
      return {
        // 当切换到新路由时，页面滚到顶部
        top: 0,
        // el: to.hash, // 锚点
        behavior: 'smooth' // 滚动平滑（动画）
      }
    }
  }
})

/**
 * 动态加载路由
 */
// 处理菜单组件路径
const routeParentName = 'Layout'
// 递归所有路由挂载在Layout组件下
function handleMenuComponent(list: any) {
  if (!list || !list.length) return
  list.forEach((item: any) => {
    if (!item.children || !item.children.length) {
      const componentPath = '@/views' + item.path + '/index.vue'
      console.log(componentPath)
      item.component = () => import('@/views' + item.path + '/index.vue')
      /**
       * 添加路由
       * @param routeParentName: 需要挂载的父级组件名
       * @param item: 路由规则
       */
      router.addRoute(routeParentName, item)
    } else {
      // router.addRoute(routeParentName, item)
      // routeParentName = item.name
      handleMenuComponent(item.children)
    }
  })
}
/**
 * 全局前置守卫
 * @param to: 即将要进入的目标 用一种标准化的方式
 * @param from: 当前导航正要离开的路由 用一种标准化的方式
 * @param next: 路由放行与跳转
 * 场景：登录校验等
 */
router.beforeEach(async (to: RouteLocationNormalized) => {
  // 开启进度条
  NProgress.start()
  const token = useStorage.getItem(TOKEN, useStorageType.Cookies)
  /* 1.用户未登录操作 */
  if (!token) {
    // 1.1 避免无限重定向
    if (!ROUTE_WHITE_LIST.includes(to.path)) return LOGIN_PATH
    // if (!ROUTE_WHITE_LIST.includes(to.path)) return { path: LOGIN_PATH, query: { redirect: to.fullPath } }
  } else {
    /* 2.用户已登录操作 */
    /* const userStore = useUserStore()
    // 2.1 是否有用户信息
    if (!userStore.userInfo) {
      console.log('没有用户信息，重新获取')
      await userStore.getUserInfoAction()
    } */
    // 2.2 是否动态添加过路由
    const layoutStore = useLayoutStore()
    if (!layoutStore.isAddRoute) {
      console.log('页面刷新，重新获取菜单与处理动态添加路由')
      let menuList: any = []
      /* 菜单处理 */
      if (!layoutStore.menuList.length) {
        // 从服务器获取
        menuList = [
          {
            name: 'Main',
            path: '/main',
            meta: {
              menuName: '首页',
              menuCode: 'Main',
              icon: 'location'
            },
            component: null
          },
          {
            name: 'Components',
            path: '/components',
            meta: {
              menuName: '组件',
              menuCode: 'Components',
              icon: 'location'
            },
            children: [
              {
                name: 'ComponentsButton',
                path: '/components/button',
                component: null,
                meta: {
                  menuName: '按钮组件',
                  menuCode: 'ComponentsButton',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsChart',
                path: '/components/chart',
                component: null,
                meta: {
                  menuName: '图表组件',
                  menuCode: 'ComponentsChart',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsTrend',
                path: '/components/trend',
                component: null,
                meta: {
                  menuName: '趋势展示组件',
                  menuCode: 'ComponentsTrend',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsProgress',
                path: '/components/progress',
                component: null,
                meta: {
                  menuName: '进度条组件',
                  menuCode: 'ComponentsProgress',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsForm',
                path: '/components/form',
                component: null,
                meta: {
                  menuName: '表单组件',
                  menuCode: 'ComponentsForm',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsDialogForm',
                path: '/components/dialogForm',
                component: null,
                meta: {
                  menuName: '对话框表单组件',
                  menuCode: 'ComponentsDialogForm',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsTableCommon',
                path: '/components/tableCommon',
                component: null,
                meta: {
                  menuName: '通用表格组件',
                  menuCode: 'ComponentsTableCommon',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsTable',
                path: '/components/table',
                component: null,
                meta: {
                  menuName: '表格组件',
                  menuCode: 'ComponentsTable',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsPagination',
                path: '/components/pagination',
                component: null,
                meta: {
                  menuName: '分页组件',
                  menuCode: 'ComponentsPagination',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsTree',
                path: '/components/tree',
                component: null,
                meta: {
                  menuName: '树组件',
                  menuCode: 'ComponentsTree',
                  icon: 'location'
                }
              },
              {
                name: 'ComponentsPage',
                path: '/components/page',
                component: null,
                meta: {
                  menuName: '页面组件',
                  menuCode: 'ComponentsPage',
                  icon: 'location'
                }
              }
            ]
          },
          {
            name: 'Rbac',
            path: '/rbac',
            meta: {
              menuName: '后台管理',
              menuCode: 'Rbac',
              icon: 'location'
            },
            component: null,
            children: [
              {
                name: 'RbacUser',
                path: '/rbac/user',
                component: null,
                meta: {
                  menuName: '用户管理',
                  menuCode: 'RbacUser',
                  icon: 'location'
                }
              },
              {
                name: 'RbacRole',
                path: '/rbac/role',
                component: null,
                meta: {
                  menuName: '角色管理',
                  menuCode: 'RbacRole',
                  icon: 'location'
                }
              },
              {
                name: 'RbacPermission',
                path: '/rbac/permission',
                component: null,
                meta: {
                  menuName: '权限管理',
                  menuCode: 'RbacPermission',
                  icon: 'location'
                }
              }
            ]
          }
        ]
      } else {
        // 从缓存获取
        menuList = layoutStore.menuList
      }
      /* 动态添加路由 */
      handleMenuComponent(menuList)
      /* 动态添加报错页面（一定要最后添加，不然先进错误页面了） */
      const errorList = [
        {
          name: '404',
          path: '/404',
          meta: {
            title: '页面未找到'
          },
          component: () => import(/* webpackChunkName: "404" */ '@/views/error/404.vue')
        },
        {
          path: '/:pathMatch(.*)*',
          redirect: '/404' // 路径不对跳转该页面
        }
      ]
      errorList.forEach((item: RouteRecordRaw) => {
        router.addRoute(item)
      })
      // console.log('查看现有路由', router.getRoutes())
      /* 缓存数据 */
      layoutStore.$patch({
        isAddRoute: true, // 缓存是否动态添加过菜单避免递归
        menuList // 缓存菜单
      })
      return { ...to, replace: true }
      // return to.path
    }
    // 2.3 如果不在白名单 就同步选中菜单与选中tag
    if (!ROUTE_WHITE_LIST.includes(to.path)) {
      const item: any = router.getRoutes().find((item: any) => item.path === to.path)
      if (!item || JSON.stringify(item) === '{}') return
      const tag = {
        name: item.name,
        path: item.path,
        meta: item.meta
      }
      /* 同步选中tags - 设置并存储tags列表 */
      layoutStore.setTagsListAction(tag)
      /* 同步选中菜单 - 设置并存储当前菜单 */
      layoutStore.setMenuActivePathAction(tag.path)
    }
    // 2.4 如果是登录页就跳转当前页或首页
    if (to.path === LOGIN_PATH) return layoutStore.menuActivePath || '/'
  }
})
/**
 * 全局后置守卫
 * @param to: 即将要进入的目标 用一种标准化的方式
 * @param from: 当前导航正要离开的路由 用一种标准化的方式
 * @param failure: 检测导航故障
 * 场景：分析、更改页面标题、声明页面等辅助功能
 */
router.afterEach((to, from, failure) => {
  if (failure) return false
  // 关闭进度条
  NProgress.done()
  // 设置网页标题
  // document.title = (to.meta.title) as string
})

export default router
